#pragma once
// ======================================================================
// [文法]: 每一行就是一个 expr
// * expr:
// *        term | expr '+' term | expr '-' term
// * term:
// *        factor | term '*' factor | term '/' factor | term '%' factor
// * factor:
// *        primary | primary '^' factor
// * primary:
// *        '(' expr ')' | number | - number | + number
// 
// =========> 消除左递归、左公共因子： (null -> 空串)
// 
// * expr   --> term E
// * E      --> + term E | - term E | null
// * term   --> factor T
// * T      --> * factor T | / factor T | null
// * factor --> primary F
// * F      --> ^ factor | null
// * primary --> ( expr ) | number | + number | - number
// ======================================================================

#include "TokenStream.h"

namespace cal
{

class Calculator
{
public:
    Calculator() = default;
    ~Calculator() = default;

public:
    header::Number calculate(const std::string& expression);
    bool quit() const { return _quit; }

private:
    void expr(TokenStream& ts);
    void E(TokenStream& ts);
    void term(TokenStream& ts);    
    void T(TokenStream& ts);
    void factor(TokenStream& ts);
    void F(TokenStream& ts);
    void primary(TokenStream& ts);

private:
    header::Number _val;
    bool           _quit;
};

}   // namespace cal
